home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / Replacements / cpdist_0_17.lha / cpdist-0.17 / source / getkey.c < prev    next >
C/C++ Source or Header  |  1994-06-06  |  6KB  |  279 lines

  1. /*
  2.  *  GETKEY.C
  3.  *
  4.  *  (c)Copyright 1990 by Tobias Ferber,  All Rights Reserved.
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include "getkey.h"
  9.  
  10.  
  11. /* Note: Turbo C Version 1.0 can *NOT* read from non-buffered streams */
  12. #if defined(__TURBOC__)
  13. #undef getkey
  14. #include <conio.h>
  15. int getkey(void) { return getch(); }
  16.  
  17.  
  18. #elif defined(GNUDOS)
  19.  
  20. int getkey(void)
  21. /* read from a non-buffered, binary opened console stream */
  22. {
  23.   FILE *con; /* the console stream */
  24.   int key;
  25.  
  26.   /* you *MUST* open the console in binary mode for DJGPP
  27.    * in order to really get a non-buffered stream via setvbuf()! */
  28.  
  29.   if( con= fopen(CONSOLENAME,"rb") )
  30.   {
  31.     setvbuf(con,0L,_IONBF,0L);  /* better than setbuf(con,0L); ? */ 
  32.  
  33.     if(ferror(con))
  34.       clearerr(con);
  35.  
  36.     fflush(con);
  37.  
  38.     key= (int)fgetc(con);
  39.  
  40.     fclose(con);
  41.   }
  42.   else key= stdin ? (int)fgetc(stdin) : 0;
  43.  
  44.   return key;
  45. }
  46.  
  47.  
  48. #elif defined(__MSDOS__)
  49. #include <dos.h>
  50.  
  51. /*
  52.  * The following stuff is implemented in the c.lib of DJGPP and is
  53.  * Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  54.  *
  55.  *      .globl  _getkey
  56.  * _getkey:
  57.  *      pushl   %ebx
  58.  *      pushl   %esi
  59.  *      pushl   %edi
  60.  *      movb    $0,%ah
  61.  *      int     $0x16
  62.  *      cmpb    $0,%al
  63.  *      jnz     L1
  64.  *      movb    %ah,%al
  65.  *      movb    $1,%ah
  66.  *      jmp     L2
  67.  * L1:
  68.  *      movb    $0,%ah
  69.  * L2:
  70.  *      andl    $0xffff,%eax
  71.  *      popl    %edi
  72.  *      popl    %esi
  73.  *      popl    %ebx
  74.  *      ret
  75.  */
  76.  
  77. int getkey(void)
  78. /* returns the keycode of the last pressed key using BIOS */
  79. {
  80.   union REGS regs;          /* defined in <dos.h> */
  81.   regs.h.ah= 0x10;          /* get MF-II keycode function # */
  82.   int86(0x16,®s,®s);  /* int 16h -> keycode in regs.x.ax */
  83.   return (unsigned short)regs.x.ax;
  84. }
  85.  
  86.  
  87. #elif defined(AMIGA)
  88.  
  89. #include <exec/types.h>
  90. #include <exec/ports.h>
  91. #include <exec/memory.h>
  92. #include <libraries/dos.h>
  93. #include <libraries/dosextens.h>
  94.  
  95. /*
  96.  * Function - SendPacket written by Phil Lindsay, Carolyn Scheppner, and Andy
  97.  * Finkel. This function will send a packet of the given type to the Message
  98.  * Port supplied.
  99.  */
  100.  
  101. typedef struct StandardPacket StandardPacket;
  102.  
  103. long
  104. SendPacket(pid, action, args, nargs)
  105. struct MsgPort *pid;    /* process indentifier ... (handler's message port) */
  106. long action;    /* packet type ... (what you want handler to do) */
  107. long *args;     /* a pointer to an argument list */
  108. long nargs;     /* number of arguments in list */
  109. {
  110.     struct MsgPort *replyport;
  111.     StandardPacket *packet;
  112.     long count, *pargs, res1;
  113.  
  114.     replyport= (struct MsgPort *)CreatePort(NULL, 0L);
  115.     if (!replyport)
  116.     return(0);
  117.  
  118.     /* Allocate space for a packet, make it public and clear it */
  119.  
  120.     packet = (StandardPacket *)
  121.       AllocMem(sizeof(StandardPacket), MEMF_PUBLIC | MEMF_CLEAR);
  122.  
  123.     if (!packet) {
  124.     DeletePort(replyport);
  125.     return(0);
  126.     }
  127.     packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
  128.     packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
  129.     packet->sp_Pkt.dp_Port = replyport;
  130.     packet->sp_Pkt.dp_Type = action;
  131.  
  132.     /* copy the args into the packet */
  133.  
  134.     pargs = &(packet->sp_Pkt.dp_Arg1);      /* address of first argument */
  135.     for (count = 0; count < nargs; count++)
  136.     pargs[count] = args[count];
  137.  
  138.     PutMsg(pid, &packet->sp_Msg);   /* send packet */
  139.  
  140.     WaitPort(replyport);
  141.     GetMsg(replyport);
  142.  
  143.     res1 = packet->sp_Pkt.dp_Res1;
  144.  
  145.     FreeMem(packet, sizeof(StandardPacket));
  146.     DeletePort(replyport);
  147.  
  148.     return (res1);
  149. }
  150.  
  151. int getkey(void)
  152. {
  153.   int key= 0;  /* the one we're going to return */
  154.   BPTR con;    /* BCPL pointer to a struct FileHandle */
  155.  
  156.   /* We must use Open() here -- not Input() -- because last may
  157.    * be redirected. */
  158.  
  159.   con= Open( CONSOLENAME, MODE_OLDFILE );
  160.  
  161.   if( BADDR(con) && IsInteractive(con) ) 
  162.   {
  163.     struct MsgPort *mp;
  164.     long arg[1], res;
  165.  
  166.     mp = ((struct FileHandle *)(BADDR(con)))->fh_Type;
  167.     arg[0]= -1L;   /* make it RAW */
  168.     res= SendPacket(mp, ACTION_SCREEN_MODE, arg, 1);
  169.  
  170.     if(res)
  171.     {
  172.       char buffer[4];     /* just to be sure... */
  173.       long actualLength;  /* return value */
  174.  
  175.       /* The value returned by Read() is the length of the information
  176.        * actually read.  So when 'actualLength' is > 0, then it is the
  177.        * number of characters read.  A value of zero means that the
  178.        * end-of-file has been reached.  Errors are indicated by a value
  179.        * of -1.  Note:  Read is an unbuffered routine. */
  180.  
  181.       actualLength = Read( con, buffer, (long)sizeof(buffer)-1 );
  182.                       /* 1 extra (for the bugs) */
  183.       if(actualLength > 0)
  184.     key= (int)buffer[0];
  185.  
  186.       arg[0]= 0L;  /* make it COOKED */
  187.       (void)SendPacket(mp, ACTION_SCREEN_MODE, arg, 1);
  188.     }
  189.  
  190.     /* Note that we must close 'con' again, whereas Input() must NEVER
  191.      * be closed. */
  192.  
  193.     Close(con);
  194.   }
  195.  
  196.   if(!key)
  197.     key= getchar();  /* just to be sure... */
  198.  
  199.   return key;
  200. }
  201.  
  202.  
  203. #elif defined(unix) || defined(__alpha)
  204.  
  205. #include <curses.h>
  206.  
  207. int getkey(void)
  208. {
  209.   char c;
  210.  
  211. #ifdef OBSOLETE
  212.  
  213.   /* try /dev/tty.  If that doesn't work, use file descriptor 2,
  214.    * which in Unix is usually attached to the screen, but also
  215.    * usually lets you read from the keyboard. */
  216.  
  217.   int tty= open("/dev/tty", 0);
  218.   if(tty < 0)
  219.     tty= 2;
  220.  
  221.   { int result;
  222.     do {
  223.       result= read(tty, &c, sizeof(char));
  224.     } while( result != 1 );
  225.   }
  226.  
  227.   if(tty!=2)
  228.     close(tty);
  229.  
  230. #else /* POSIX */
  231.  
  232.   initscr();
  233.   savetty();
  234.   cbreak();
  235.   noecho();
  236.   c= getch();
  237.   resetty();
  238.   endwin();
  239.  
  240. #endif
  241.  
  242.   return c;
  243.  
  244. #endif /* which machine? */
  245.  
  246.  
  247. #ifdef TEST
  248. #include <stdlib.h>
  249.  
  250. main(int argc, char **argv)
  251. {
  252.   int err= 0;
  253.  
  254.   if(argc==2)
  255.   {
  256.     char *s= argv[1];
  257.     do {
  258.       char c= getkey();
  259. #ifdef DEBUG
  260.       printf("getkey() returned 0x%02x\n",c)
  261. #endif
  262.       for(err=0; s[err]!='\0'; err++)
  263.         if(c==s[err])
  264.           break;
  265.     } while(s[err]=='\0');
  266.   }
  267.   else
  268.   { puts("GETKEY [keys]\n\n"
  269.          "GetKey wartet auf eine der Tasten in 'keys' und gibt den\n"
  270.          "Index der gedrueckten Taste aus 'keys' im Errorlevel zurueck");
  271.   }
  272. #ifdef DEBUG
  273.   printf("errorlevel=%d\n",err);
  274. #endif
  275.   exit(err);
  276. }
  277. #endif /* TEST */
  278.